/*
Simple 80 Processor (mz80) V1.0
-- A variant of my80 --
(C)Copyright by Naohiko Shimizu, 2001,2002.
All rights are reserved.
Contact information:
Dr. Naohiko Shimizu
School of Information Technology and Electronics, Tokai University
1117 Kitakaname, Hiratsuka-city, Kanagawa, 259-1292, Japan
email: nshimizu@keyaki.cc.u-tokai.ac.jp
URL: http://shimizu-lab.et.u-tokai.ac.jp/
Update informations:
18-May-2002: PUSH register conflict, SHMZ
27-Apr-2002: Add EDxx instructions, SHMZ
26-Apr-2002: Add CBxx instructions, SHMZ
26-Apr-2002: Add JR,JRC,DJNZ, SHMZ
25-Apr-2002: Add Z80 compatible registers, EXX, EXAF, DDxx, FDxx SHMZ
20-Apr-2002: Restructuring to reduce gates, SHMZ
30-Jan-2001: Generated from the SN/1
******************************************/
%i
%i
%d B 0b000
%d C 0b001
%d D 0b010
%d E 0b011
%d H 0b100
%d L 0b101
%d F 0b110
%d A 0b111
%d M 0b110
%d SPH 0b110
%d SPL 0b111
declare mz80 {
bidirect data<8> ;
bidirect adrs<16> ;
instrin extint;
instrout memory_read;
instrout memory_write;
instrout io_read;
instrout io_write;
instrout reti;
instrout retn;
}
declare mz80core {
input data<8> ;
output datao<8> ;
output adrs<16> ;
instrin extint;
instrout memory_read;
instrout memory_write;
instrout io_read;
instrout io_write;
instrout reti;
instrout retn;
}
declare alu80 {
input in1<8> ;
input in2<8> ;
input ci ;
output out<8> ;
output s,z,a,p,c;
instrin add,adc,sub,sbc,and,or,xor,cmp,thr,neg;
instrin rlc, rrc, rl, rr, sla, sra, sls, srl,inc,dec,incc,decc;
input inb<3> ;
instrin bit, res, set;
instr_arg inc(in1);
instr_arg dec(in1);
instr_arg incc(in1,ci);
instr_arg decc(in1,ci);
instr_arg thr(in1);
instr_arg neg(in1);
instr_arg adc(in1,in2,ci);
instr_arg sbc(in1,in2,ci);
instr_arg add(in1,in2);
instr_arg sub(in1,in2);
instr_arg and(in1,in2);
instr_arg or (in1,in2);
instr_arg xor(in1,in2);
instr_arg cmp(in1,in2);
instr_arg rlc(in1);
instr_arg rrc(in1);
instr_arg rl(in1,ci);
instr_arg rr(in1,ci);
instr_arg sla(in1);
instr_arg sra(in1);
instr_arg srl(in1);
instr_arg sls(in1);
instr_arg bit(in1, inb);
instr_arg res(in1, inb);
instr_arg set(in1, inb);
}
declare cpa {
input in1, in2, ci;
output out, co;
instrin do;
instr_arg do(in1,in2,ci);
}
declare cpa4 {
input in1<4>, in2<4>, ci;
output out<4>, co;
instrin do;
instr_arg do(in1,in2,ci);
}
declare cpa8 {
input in1<8>, in2<8>, ci;
output out<8>, co, ca;
instrin do;
instr_arg do(in1,in2,ci);
}
module cpa {
input in1, in2, ci;
output out, co;
instrin do;
instruct do par {
out = in1 @ in2 @ ci;
co = (in1&in2)|(in1&ci)|(in2&ci);
}
}
module cpa4 {
input in1<4>, in2<4>, ci;
output out<4>, co;
cpa a1,a2,a3,a4;
instrin do;
instruct do par {
out = a4.do(in1<3>,in2<3>,a3.co).out ||
a3.do(in1<2>,in2<2>,a2.co).out ||
a2.do(in1<1>,in2<1>,a1.co).out ||
a1.do(in1<0>,in2<0>,ci).out;
co = a4.co;
}
}
module cpa8 {
input in1<8>, in2<8>, ci;
output out<8>, co, ca;
cpa4 a1,a2;
instrin do;
instruct do par {
out = a2.do(in1<7:4>,in2<7:4>,a1.co).out ||
a1.do(in1<3:0>,in2<3:0>,ci).out;
co = a2.co;
ca = a1.co;
}
}
declare ha {
input in, ci, dec;
output out, co;
instrin do;
instr_arg do(in,ci,dec);
}
declare inc4 {
input in<4>, ci,dec;
output out<4>, co;
instrin do;
instr_arg do(in,ci,dec);
}
declare inc8 {
input in<8>, ci;
output out<8>, co;
instrin up,down;
instr_arg up(in,ci);
instr_arg down(in,ci);
}
module ha {
input in, ci,dec;
output out, co;
instrin do;
instruct do par {
out = in @ ci;
co = ((in @ dec)&ci);
}
}
module inc4 {
input in<4>, ci, dec;
output out<4>, co;
ha a1,a2,a3,a4;
instrin do;
instruct do par {
out = a4.do(in<3>,a3.co,dec).out ||
a3.do(in<2>,a2.co,dec).out ||
a2.do(in<1>,a1.co,dec).out ||
a1.do(in<0>,ci,dec).out;
co = a4.co;
}
}
module inc8 {
input in<8>, ci;
output out<8>, co;
inc4 a1,a2;
instrin up,down;
instruct up par {
out = a2.do(in<7:4>,a1.co,0b0).out ||
a1.do(in<3:0>,ci,0b0).out;
co = a2.co;
}
instruct down par {
out = a2.do(in<7:4>,a1.co,0b1).out ||
a1.do(in<3:0>,ci,0b1).out;
co = a2.co;
}
}
module alu80 {
input in1<8> ;
input in2<8> ;
input inb<3> ;
input ci ;
output out<8> ;
output s,z,a,p,c;
instrin add,adc,sub,sbc,and,or,xor,cmp,thr,neg;
instrin rlc, rrc, rl, rr, sla, sra, sls, srl,inc,dec,incc,decc;
instrin bit, res, set;
cpa8 cpa;
instruct thr par {
out = in1;
c = 0b0; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct neg par {
out = cpa.do(0x00, ^in1, 0b1).out;
c = ^cpa.co; a=^cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct inc par {
out = cpa.do(in1, 0x01, 0b0).out;
c = cpa.co; a=cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct add par {
out = cpa.do(in1, in2, 0b0).out;
c = cpa.co; a=cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct adc par {
out = cpa.do(in1, in2, ci).out;
c = cpa.co; a=cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct incc par {
out = cpa.do(in1, 0x00, ci).out;
c = cpa.co; a=cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct sub par {
out = cpa.do(in1, ^in2, 0b1).out;
c = ^cpa.co; a=^cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct sbc par {
out = cpa.do(in1, ^in2, ^ci).out;
c = ^cpa.co; a=^cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct dec par {
out = cpa.do(in1, ^0x01, 0b1).out;
c = ^cpa.co; a=^cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct decc par {
out = cpa.do(in1, ^0x00, ^ci).out;
c = ^cpa.co; a=^cpa.ca;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct and par {
out = in1 & in2;
c = 0b0; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct xor par {
out = in1 @ in2;
c = 0b0; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct or par {
out = in1 | in2;
c = 0b0; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct cmp par {
out = in1;
cpa.do(in1, ^in2, 0b1);
c = ^cpa.co; a=^cpa.ca;
s = cpa.out<7>; z = ^/| cpa.out; p = ^/@ cpa.out;
}
instruct rlc par {
out = in1<6:0>||in1<7>;
c = in1<7>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct rrc par {
out = in1<0>||in1<7:1>;
c = in1<0>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct rl par {
out = in1<6:0>||ci;
c = in1<7>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct rr par {
out = ci||in1<7:1>;
c = in1<0>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct sla par {
out = in1<6:0>||0b0;
c = in1<7>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct sra par {
out = in1<7>||in1<7:1>;
c = in1<0>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct srl par {
out = 0b0||in1<7:1>;
c = in1<0>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct sls par {
out = in1<6:0>||0b1;
c = in1<7>; a=0b0;
s = out<7>; z = ^/| out; p = ^/@ out;
}
instruct bit any {
inb == 0b000: z = (in1<0> & 0b1);
inb == 0b001: z = (in1<1> & 0b1);
inb == 0b010: z = (in1<2> & 0b1);
inb == 0b011: z = (in1<3> & 0b1);
inb == 0b100: z = (in1<4> & 0b1);
inb == 0b101: z = (in1<5> & 0b1);
inb == 0b110: z = (in1<6> & 0b1);
inb == 0b111: z = (in1<7> & 0b1);
}
instruct set any {
inb == 0b000: out = (in1 | 0x01);
inb == 0b001: out = (in1 | 0x02);
inb == 0b010: out = (in1 | 0x04);
inb == 0b011: out = (in1 | 0x08);
inb == 0b100: out = (in1 | 0x10);
inb == 0b101: out = (in1 | 0x20);
inb == 0b110: out = (in1 | 0x40);
inb == 0b111: out = (in1 | 0x80);
}
instruct res any {
inb == 0b000: out = (in1 & ^0x01);
inb == 0b001: out = (in1 & ^0x02);
inb == 0b010: out = (in1 & ^0x04);
inb == 0b011: out = (in1 & ^0x08);
inb == 0b100: out = (in1 & ^0x10);
inb == 0b101: out = (in1 & ^0x20);
inb == 0b110: out = (in1 & ^0x40);
inb == 0b111: out = (in1 & ^0x80);
}
}
declare ram {
input adr<8>;
bidirect data<8>;
instrin read;
instrin write;
instr_arg read(adr);
instr_arg write(adr,data);
}
module ram {
input adr<8>;
bidirect data<8>;
r256_8 m;
instrin read;
instrin write;
instruct read data = m.read(adr).dout;
instruct write m.write(adr,data);
}
module top {
output outp<8>;
output adrs<16>;
input inp<8>;
mz80 cpu;
ram ram;
instruct cpu.memory_read cpu.data = ram.read(cpu.adrs<7:0>).data ;
instruct cpu.memory_write ram.write(cpu.adrs<7:0>,cpu.data);
instruct cpu.io_read cpu.data = inp;
instruct cpu.io_write outp = cpu.data;
}
module mz80 {
bidirect data<8> ;
bidirect adrs<16> ;
instrin extint;
instrout memory_read;
instrout memory_write;
instrout io_read;
instrout io_write;
instrout reti;
instrout retn;
mz80core cpu;
instruct extint cpu.extint();
instruct cpu.memory_read par {
cpu.data = data ;
adrs = cpu.adrs;
memory_read();
}
instruct cpu.io_read par {
cpu.data = data ;
adrs = cpu.adrs;
io_read();
}
instruct cpu.memory_write par {
data = cpu.datao;
adrs = cpu.adrs;
memory_write();
}
instruct cpu.io_write par {
data = cpu.datao;
adrs = cpu.adrs;
io_write();
}
}
module mz80core {
input data<8> ;
output datao<8> ;
output adrs<16> ;
instrin extint;
instrself start, setreg, getreg, setrx, getrx, flagchk,
decop, incop, incsp, incpc, loop1, lospl, lopcl,
decsp, decpc, setflag, deccb, deced;
instrself dmov,dalu,dinr,ddad,dinx,dpop,dpush,dldax,dstax,dretc,drst,
dalum,dret,dxthl,dpchl,dsphl,dxchg,ddi,dei,dnop;
instrself dmvi,dalui,din,dout,dcc,dcall,djmp,djc,dlxi,dlda,
dlhld,dshld,dsta, dexx, dexaf, ddd, dfd;
instrself zjr,zjrc,zdjnz,dcb,ded,zcb,zed,zflagchk;
instrself zio,zaddsub,zld,zrd,zret,zblk,zmisc,zneg;
instrself zrlc, zrrc, zrl, zrr, zsla, zsra, zsls, zsrl, zbit, zres, zset;
instrself fetch2, fetch3, ifetch, run0, run1, run2, run3, run4;
instrself run5,run6,run7,run8, runex;
instrout memory_read, memory_write;
instrout io_read, io_write;
instrout reti, retn;
reg pch<8>,pcl<8>; /* program counter */
reg sph<8>,spl<8>;
reg ixh<8>,ixl<8>;
reg iyh<8>,iyl<8>;
reg a0<8>,f0<8>,b0<8>,c0<8>,d0<8>,e0<8>,h0<8>,l0<8>;
reg a1<8>,f1<8>,b1<8>,c1<8>,d1<8>,e1<8>,h1<8>,l1<8>;
reg tc, imask, op0<8>, op1<8>, op2<8>, tmp<8>;
reg_wr st0, regset, regaf ,dd, fd ;
reg st1,st2 ;
inc8 inc ;
alu80 alu ;
sel_v lo<8>, flg, rs<3>, rg<3>, v<8>, w<8>, fi<8> ;
sel a<8>,f<8>,b<8>,c<8>,d<8>,e<8>,h<8>,l<8>;
instr_arg memory_read(adrs);
instr_arg memory_write(adrs,datao);
instr_arg io_read(adrs);
instr_arg io_write(adrs,datao);
instr_arg setreg(rs,v);
instr_arg getreg(rg);
instr_arg setrx(rs,v);
instr_arg getrx(rg);
instr_arg decop();
instr_arg deccb();
instr_arg deced();
instr_arg setflag(fi);
stage_name int {
task intt() ;
}
stage_name if {
task start(pch,pcl) ;
task run();
}
stage_name ex {
task run();
task run1();
task run2();
task run3();
task run4();
}
stage_name cb {
task run();
task run1();
task run2();
task run3();
task run4();
}
stage_name ed {
task run();
task run1();
task run2();
task run3();
task run4();
task run5();
task run6();
task run7();
task run8();
}
/* Common operations for every stages must be described here */
par{
st0 := 0b1;
st1 := st0;
st2 := st1;
if ((st2 == 0b0) & (st1 == 0b1)) start();
any {
^regset: par {
b=b0; c=c0; d=d0; e=e0;
}
regset: par {
b=b1; c=c1; d=d1; e=e1;
}
^regaf: par {
a=a0; f=f0;
}
regaf: par {
a=a1; f=f1;
}
}
any {
dd: par { h=ixh; l=ixl; }
fd: par { h=iyh; l=iyl; }
else: any {
^regset: par {h=h0; l=l0;}
regset: par {h=h1; l=l1;}
}
}
}
instruct extint generate int.intt();
instruct start par {
/* start instruction fetch */
generate if.start(0x00,0x00);
imask := 0b1;
}
instruct loop1 lo = op1;
instruct lospl lo = spl;
instruct lopcl lo = pcl;
instruct setreg any {
^regset & (rs == B): b0:=v;
regset & (rs == B): b1:=v;
^regset & (rs == C): c0:=v;
regset & (rs == C): c1:=v;
^regset & (rs == D): d0:=v;
regset & (rs == D): d1:=v;
^regset & (rs == E): e0:=v;
regset & (rs == E): e1:=v;
rs == H: any {
dd: ixh := v;
fd: iyh := v;
else: any {
^regset: h0:=v;
regset: h1:=v;
}
}
rs == L: any {
dd: ixl := v;
fd: iyl := v;
else: any {
^regset: l0:=v;
regset: l1:=v;
}
}
^regaf & (rs == F): f0:=v;
^regaf & (rs == A): a0:=v;
regaf & (rs == F): f1:=v;
regaf & (rs == A): a1:=v;
}
instruct getreg any {
rg == B: lo = b;
rg == C: lo = c;
rg == D: lo = d;
rg == E: lo = e;
rg == H: lo = h;
rg == L: lo = l;
rg == F: lo = f;
rg == A: lo = a;
}
instruct setrx any {
rs == SPH: sph:=v;
rs == SPL: spl:=v;
regset & (rs == B): b1:=v;
^regset & (rs == B): b0:=v;
regset & (rs == C): c1:=v;
^regset & (rs == C): c0:=v;
regset & (rs == D): d1:=v;
^regset & (rs == D): d0:=v;
regset & (rs == E): e1:=v;
^regset & (rs == E): e0:=v;
rs == H: any {
dd: ixh := v;
fd: iyh := v;
else: any {
^regset: h0:=v;
regset: h1:=v;
}
}
rs == L: any {
dd: ixl := v;
fd: iyl := v;
else: any {
^regset: l0:=v;
regset: l1:=v;
}
}
}
instruct getrx any {
rg == B: lo = b;
rg == C: lo = c;
rg == D: lo = d;
rg == E: lo = e;
rg == H: lo = h;
rg == L: lo = l;
rg == SPH: lo = sph;
rg == SPL: lo = spl;
}
instruct setflag any {
^regaf: f0:=fi;
regaf: f1:=fi;
}
instruct flagchk any {
op0<5:3> == 0b000: flg = ^f<6>;
op0<5:3> == 0b001: flg = f<6>;
op0<5:3> == 0b010: flg = ^f<0>;
op0<5:3> == 0b011: flg = f<0>;
op0<5:3> == 0b100: flg = ^f<2>;
op0<5:3> == 0b101: flg = f<2>;
op0<5:3> == 0b110: flg = ^f<7>;
op0<5:3> == 0b111: flg = f<7>;
}
instruct zflagchk any {
op0<4:3> == 0b00: flg = ^f<6>;
op0<4:3> == 0b01: flg = f<6>;
op0<4:3> == 0b10: flg = ^f<0>;
op0<4:3> == 0b11: flg = f<0>;
}
instruct deccb any {
(op0<7:6> == 0b00): zrlc();
(op0<7:6> == 0b01): zbit();
(op0<7> == 0b1): zres();
}
instruct deced any {
((op0<7:6> || op0<2:1>) == 0b0100): zio();
((op0<7:6> || op0<2:0>) == 0b01010): zaddsub();
((op0<7:6> || op0<2:0>) == 0b01011): zld();
((op0<7:4> || op0<2:0>) == 0b0110111): zrd();
((op0<7:4> || op0<2:0>) == 0b0100101): zret();
((op0<7:5> || op0<2>) == 0b1010): zblk();
((op0<7:5> || op0<2>) == 0b0101): zmisc();
(op0 == 0x44): zneg();
}
instruct decop any {
(op0<7:6> == 0b01): dmov();
(op0<7:6> == 0b10): dalu();
((op0<7:6> || op0<2:1>) == 0b0010): dinr();
((op0<7:6> || op0<3:0>) == 0b001001): ddad();
((op0<7:6> || op0<2:0>) == 0b00011): dinx();
((op0<7:6> || op0<3:0>) == 0b110001): dpop();
((op0<7:6> || op0<3:0>) == 0b110101): dpush();
((op0<7:5> || op0<3:0>) == 0b0001010): dldax();
((op0<7:5> || op0<3:0>) == 0b0000010): dstax();
((op0<7:6> || op0<2:0>) == 0b11000): dretc();
((op0<7:6> || op0<2:0>) == 0b11111): drst();
((op0<7:6> || op0<2:0>) == 0b00111): dalum();
(op0 == 0xc9): dret();
(op0 == 0xe3): dxthl();
(op0 == 0xe9): dpchl();
(op0 == 0xf9): dsphl();
(op0 == 0xeb): dxchg();
(op0 == 0xf3): ddi();
(op0 == 0xfb): dei();
(op0 == 0x00): dnop();
((op0<7:6>||op0<2:0>) == 0b00110): dmvi();
((op0<7:6>||op0<2:0>) == 0b11110): dalui();
(op0 == 0xdb): din();
(op0 == 0xd3): dout();
((op0<7:6>||op0<2:0>) == 0b11100): dcc();
((op0<7:6>||op0<2:0>) == 0b11010): djc();
((op0<7:6>||op0<3:0>) == 0b000001): dlxi();
(op0 == 0xcd): dcall();
(op0 == 0xc3): djmp();
(op0 == 0x3a): dlda();
(op0 == 0x2a): dlhld();
(op0 == 0x22): dshld();
(op0 == 0x32): dsta();
(op0 == 0xd9): dexx();
(op0 == 0x08): dexaf();
(op0 == 0xdd): ddd();
(op0 == 0xfd): dfd();
(op0 == 0xcb): dcb();
(op0 == 0xed): ded();
(op0 == 0x10): zdjnz();
(op0 == 0x18): zjr();
((op0<7:5>||op0<2:0>) == 0b001000): zjrc();
}
%d OP2OP1 0b00
%d HL 0b01
%d SP 0b10
%d PC 0b11
instruct incop par {
op1:=alu.inc(loop1().lo).out;
op2:=inc.up(op2,alu.c).out;}
instruct incsp par {
spl:=alu.inc(lospl().lo).out;
sph:=inc.up(sph,alu.c).out;}
instruct incpc par {
pcl:=alu.inc(lopcl().lo).out;
pch:=inc.up(pch,alu.c).out;}
instruct decsp par {
spl:=alu.dec(spl).out;
sph:=inc.down(sph,alu.c).out;}
instruct decpc par {
pcl:=alu.dec(lopcl().lo).out;
pch:=inc.down(pch,alu.c).out;}
instruct dmov any {
ex.run: par { /* MOV, HLT */
any {
op0<5:0> == 0b110110: par {
decpc();
ifetch();
}
else: any {
(op0<2:0> == M):
any {
dd | fd: par {
fetch2(); run2();
}
else:
par {
op1 := memory_read(h||l).data;
run1();
}
}
else: par {
op1 := getreg(op0<2:0>).lo;
run1();
}
}
}
}
ex.run1:
any {
op0<5:3> == M: any {
dd | fd: par {
fetch2(); run2();
tmp := op1;
}
else:
par {
memory_write(h||l,op1);
ifetch();
}
}
else: par {
setreg(op0<5:3>,op1);
ifetch();
}
}
ex.run2:
par {
op1 := alu.add(getreg(L).lo, op1).out;
op2 := inc.up(h,alu.c).out;
any {
op0<5:3> == M: run4();
else: run3();
}
}
ex.run3:
par {
op1 := memory_read(op2||op1).data;
run1();
}
ex.run4:
par {
memory_write(op2||op1,tmp);
ifetch();
}
}
instruct dalu any {
ex.run: any { /* ALU */
(op0<2:0> == M): any {
dd | fd: par {
fetch2(); run2();
}
else:
par {
op1 := memory_read(h||l).data;
run1();
}
}
else: par {
op1 := getreg(op0<2:0>).lo;
run1();
}
}
ex.run1: par {
any {
op0<5:3> == 0b000: alu.add(getreg(A).lo, op1);
op0<5:3> == 0b001: alu.adc(getreg(A).lo, op1, f<0>);
op0<5:3> == 0b010: alu.sub(getreg(A).lo, op1);
op0<5:3> == 0b011: alu.sbc(getreg(A).lo, op1, f<0>);
op0<5:3> == 0b100: alu.and(getreg(A).lo, op1);
op0<5:3> == 0b101: alu.xor(getreg(A).lo, op1);
op0<5:3> == 0b110: alu.or(getreg(A).lo, op1);
op0<5:3> == 0b111: alu.cmp(getreg(A).lo, op1);
}
setreg(A, alu.out);
setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||alu.c);
ifetch();
}
ex.run2:
par {
op1 := alu.add(getreg(L).lo, op1).out;
op2 := inc.up(h,alu.c).out;
run3();
}
ex.run3:
par {
op1 := memory_read(op2||op1).data;
run1();
}
}
instruct dinr any {
ex.run: any { /* INR,DCR */
(op0<5:3> == M): any {
dd | fd: par {
fetch2(); run3();
}
else: par {
op1 := memory_read(h||l).data;
run1();
}
}
else: par {
any {
^op0<0>: alu.inc(getreg(op0<5:3>).lo);
op0<0>: alu.dec(getreg(op0<5:3>).lo);
}
setreg(op0<5:3>, alu.out);
setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||f<0>);
ifetch();
}
}
ex.run1: par {
any {
^op0<0>: alu.inc(loop1().lo);
op0<0>: alu.dec(loop1().lo);
}
any {
(dd|fd): par { tmp := alu.out; op1 := tmp; }
else: op1 := alu.out;
}
setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||f<0>);
run2();
}
ex.run2: par {
any {
(dd|fd) : memory_write(op2||op1, tmp);
else: memory_write(h||l, op1);
}
ifetch();
}
ex.run3:
par {
op1 := alu.add(getreg(L).lo, op1).out;
op2 := inc.up(h,alu.c).out;
run4();
}
ex.run4:
par {
op1 := memory_read(op2||op1).data;
tmp := op1;
run1();
}
}
instruct ddad any {
ex.run: par { /* DAD */
setrx(L, alu.add(getrx(op0<5:4>||0b1).lo, l).out);
tc := alu.c;
run1();
}
ex.run1: par {
setrx(H,alu.adc(getrx(op0<5:4> || 0b0).lo, h, tc).out);
setflag(f<7:1>||alu.c);
ifetch();
}
}
instruct dinx any {
ex.run: par { /* INX,DCX */
any {
^op0<3>: alu.inc(getrx(op0<5:4> || 0b1).lo);
op0<3>: alu.dec(getrx(op0<5:4> || 0b1).lo);
}
setrx(op0<5:4> || 0b1, alu.out);
tc := alu.c;
run1();
}
ex.run1: par {
any {
^op0<3>: alu.incc(getrx(op0<5:4> || 0b0).lo, tc);
op0<3>: alu.decc(getrx(op0<5:4> || 0b0).lo, tc);
}
setrx(op0<5:4> || 0b0, alu.out);
ifetch();
}
}
instruct dpop any {
ex.run: par { /* POP */
setreg(op0<5:4> || 0b1, memory_read(sph||spl).data);
incsp();
run1();
}
ex.run1: par {
setreg(op0<5:4> || 0b0, memory_read(sph || spl).data);
incsp();
ifetch();
}
}
instruct dpush any {
ex.run: par { /* PUSH */
decsp();
run1();
}
ex.run1: par {
memory_write(sph || spl, getreg(op0<5:4> || 0b0).lo);
decsp();
run2();
}
ex.run2: par {
memory_write(sph || spl, getreg(op0<5:4> || 0b1).lo);
ifetch();
}
}
instruct dldax par { /* LDAX */
any {
^op0<4>: setreg(A,memory_read(b||c).data);
else: setreg(A,memory_read(d||e).data);
}
ifetch();
}
instruct dstax par { /* STAX */
any {
^op0<4>: memory_write(b||c,a);
else: memory_write(d||e,a);
}
ifetch();
}
instruct dretc any {
ex.run: any { /* RETC */
flagchk().flg : dret();
else: ifetch();
}
ex.run1: dret();
}
instruct dret any {
ex.run: par {
pcl := memory_read(sph||spl).data;
incsp();
run1();
}
ex.run1: par {
pch := memory_read(sph || spl).data;
incsp();
ifetch();
}
}
instruct drst any {
ex.run: par {
op1 := 0b00 || op0<5:3> || 0b000;
op2 := 0x00;
decsp();
run3();
}
else: dcall();
}
instruct dalum any {
ex.run: par { /* ALU MISC */
any {
op0<5:3> == 0b000: par { /* RLC */
setreg(A,alu.rlc(getreg(A).lo).out);
setflag(f<7:1> || alu.c);
ifetch();
}
op0<5:3> == 0b001: par { /* RRC */
setreg(A,alu.rrc(getreg(A).lo).out);
setflag(f<7:1> || alu.c);
ifetch();
}
op0<5:3> == 0b010: par { /* RAL */
setreg(A,alu.rl(getreg(A).lo,f<0>).out);
setflag(f<7:1> || alu.c);
ifetch();
}
op0<5:3> == 0b011: par { /* RAR */
setreg(A,alu.rr(getreg(A).lo,f<0>).out);
setflag(f<7:1> || alu.c);
ifetch();
}
op0<5:3> == 0b100: par { /* DAA */
if(a<3> & (a<2> | a<1>) | f<4>) par {
setreg(A,alu.add(getreg(A).lo, 0x06).out);
setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||alu.c);
}
run1();
}
op0<5:3> == 0b101: par { /* CMA */
setreg(A,^a);
ifetch();
}
op0<5:3> == 0b110: par { /* STC */
setflag(f<7:1> || 0b1);
ifetch();
}
op0<5:3> == 0b111: par { /* CMC */
setflag(f<7:1> || ^f<0>);
ifetch();
}
}
}
ex.run1: par {
if(a<7> & (a<6> | a<5>) | f<0>) par {
setreg(A,alu.add(getreg(A).lo, 0x60).out);
setflag(alu.s||alu.z||0b0||alu.a||0b0||alu.p||0b0||alu.c);
}
ifetch();
}
}
instruct dxthl any {
ex.run: par { /* XTHL */
op1:=memory_read(sph||spl).data;
run1();
}
ex.run1: par {
memory_write(sph || spl, l);
setreg(L,op1);
incsp();
run2();
}
ex.run2: par {
op1:=memory_read(sph || spl).data;
run3();
}
ex.run3: par {
setreg(H, op1);
memory_write(sph || spl, h);
decsp();
ifetch();
}
}
instruct dpchl par {
pch := h;
pcl := l;
ifetch();
}
instruct dsphl any {
ex.run: par { /* SPHL */
setrx(SPH, getreg(H).lo);
run1();
}
ex.run1: par {
setrx(SPL, getreg(L).lo);
ifetch();
}
}
instruct dxchg any {
ex.run: par { /* XCHG */
op1 := getreg(H).lo;
run1();
}
ex.run1: par {
setreg(H, getreg(D).lo);
run2();
}
ex.run2: par {
setreg(D, op1);
op1 := getreg(L).lo;
run3();
}
ex.run3: par {
setreg(L, getreg(E).lo);
run4();
}
ex.run4: par {
setreg(E, op1);
ifetch();
}
}
instruct ddi par {
imask := 0b1;
ifetch();
}
instruct dei par {
imask := 0b0;
ifetch();
}
instruct dnop par {
ifetch();
}
instruct dmvi any {
ex.run: par { /* MVI */
fetch2();
run1();
}
else: dmov();
}
instruct dalui any {
ex.run: par { /* ALU */
fetch2();
run1();
}
else: dalu();
}
instruct din any {
ex.run: par {fetch2(); run1(); }
ex.run1: par { /* IN */
setreg(A,io_read(0x00 || op1).data);
ifetch();
}
}
instruct dout any {
ex.run: par {fetch2(); run1(); }
ex.run1: par { /* OUT */
io_write(0x00 || op1,a);
ifetch();
}
}
instruct dcc any {
ex.run: par {fetch2(); run1(); }
ex.run1: par {fetch3(); run2(); }
ex.run2: any { /* CC */
flagchk().flg: dcall();
else: ifetch();
}
else: dcall();
}
instruct dcall any {
ex.run: par {fetch2(); run1(); }
ex.run1: par {fetch3(); run2(); }
ex.run2: par { /* CALL */
decsp();
run3();
}
ex.run3: par {
memory_write(sph || spl, pch);
decsp();
run4();
}
ex.run4: par {
memory_write(sph || spl, pcl);
djmp();
}
}
instruct djmp any {
ex.run: par {fetch2(); run1(); }
ex.run1: par {fetch3(); run2(); }
else: par { /* JMP */
pcl := op1;
pch := op2;
ifetch();
}
}
instruct djc any {
ex.run: par {fetch2(); run1(); }
ex.run1: par {fetch3(); run2(); }
ex.ru